-- 检查
local check_backspace = function()
  local col = vim.fn.col(".") - 1
  return col == 0 or vim.fn.getline("."):sub(col, col):match("%s")
end

return {
  "hrsh7th/nvim-cmp",
  dependencies = {
    -- 补全插件
    "hrsh7th/cmp-nvim-lsp",
    -- 路径补全插件
    "hrsh7th/cmp-path",
    "hrsh7th/cmp-buffer",
    "hrsh7th/cmp-cmdline",
    -- 第三方片段引擎
    "L3MON4D3/LuaSnip",
    "saadparwaiz1/cmp_luasnip",
    -- "rafamadriz/friendly-snippets",
  },
  config = function()
    local cmp_ok, cmp = pcall(require, "cmp")
    local luasnip_ok, luasnip = pcall(require, "luasnip")
    if not cmp_ok or not luasnip_ok then
      return
    end

    require("luasnip.loaders.from_vscode").lazy_load()

    cmp.setup({
      -- 片段引擎
      snippet = {
        expand = function(args)
          require("luasnip").lsp_expand(args.body)
        end,
      },

      -- 按键映射
      mapping = cmp.mapping.preset.insert({
        ["<C-b>"] = cmp.mapping(cmp.mapping.scroll_docs(-4), {'i', 'c'}),
        ["<C-f>"] = cmp.mapping(cmp.mapping.scroll_docs(4), {'i', 'c'}),
        ["<C-n>"] = cmp.mapping(cmp.mapping.select_next_item({
          behavior = cmp.SelectBehavior.insert
        }), {'i', 'c'}),
        ["<C-p>"] = cmp.mapping(cmp.mapping.select_prev_item({
          behavior = cmp.SelectBehavior.Insert
        }),  {'i', 'c'}),
        ["<C-.>"] = cmp.mapping.complete(),
        ["<C-e>"] = cmp.mapping.abort(),
        -- 回车 选定补全选项
        ["<CR>"] = cmp.mapping.confirm({ select = true }),
        -- Tab 在列表中选择补全选项或者跳到下一个可输入位置
        ["<Tab>"] = cmp.mapping(function(fallback)
          if cmp.visible() then
            cmp.select_next_item()
          elseif luasnip.expandable() then
            luasnip.expand()
          elseif luasnip.expand_or_jumpable() then
            luasnip.expand_or_jump()
          elseif check_backspace() then
            fallback()
          else
            fallback()
          end
        end, { "i", "s" }),
      }),

      -- 指定资源
      sources = cmp.config.sources({
        { name = 'nvim_lsp' },
        { name = 'luasnip' },
      }, {
        { name = 'buffer' },
        { name = 'path' },
      }),
    })

    -- Use buffer source for `/` and `?` (if you enabled `native_menu`, this won't work anymore).
    cmp.setup.cmdline({ '/', '?' }, {
      mapping = cmp.mapping.preset.cmdline(),
      sources = {
        { name = 'buffer' }
      }
    })

    -- Use cmdline & path source for ':' (if you enabled `native_menu`, this won't work anymore).
    cmp.setup.cmdline(':', {
      mapping = cmp.mapping.preset.cmdline(),
      sources = cmp.config.sources({
        { name = 'path' }
      }, {
        { name = 'cmdline' }
      }),
      matching = { disallow_symbol_nonprefix_matching = false }
    })
  end,
}
